﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.IO;
using VConfig;
using System.Drawing;
using System.Drawing.Imaging;
using VCommons;
using Commons.Entity;

namespace WEB.Services
{
    public class FileUpload : FileUploadBase, IFileUpload
    {
        string currPath; //当前路径
        string currFileName;//上传后的文件名

        #region 文件上传WWW服务器及图像服务器

        /// <summary>
        /// 文件流上传
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="hpf">文件流</param>
        /// <returns></returns>
        public VMessage Image(UpLoadType type, HttpPostedFileBase hpf)
        {
            return this.Image(type, hpf, false);
        }
        /// <summary>
        /// 文件流上传
        /// </summary>
        /// <param name="type">类型</param>
        /// <param name="hpf">文件流</param>
        /// <param name="IsScale">是否生成缩略图</param>
        /// <returns></returns>
        public VMessage Image(UpLoadType type, HttpPostedFileBase hpf, bool IsScale)
        {
            HttpRequest Request = HttpContext.Current.Request;
            VMessage vmsg = new VMessage();

            if (this.IsImageVaild(type, hpf))
            {

                string relativePath = string.Format(WebConstConfig.LocationUploadPath, relativePathDic[type]);
                string path = HttpContext.Current.Server.MapPath(relativePath);
                DirectoryInfo di = new DirectoryInfo(path);
                if (!di.Exists)
                {
                    di.Create();
                }
                string guid = Guid.NewGuid().ToString();
                string fileName = string.Format("{0}{1}", guid, new FileInfo(hpf.FileName).Extension);//上传文件的名称
                hpf.SaveAs(string.Format("{0}{1}", path, fileName));
                this.currPath = path;
                this.currFileName = fileName;
                if (IsScale)
                    foreach (ImageSize item in ImageSizeArr)
                    {
                        CreateThumbnail(hpf, item.Width, item.Height);//生成缩放图片
                    }


                vmsg.Clear();
                vmsg.AddItem(string.Format("{0}://{1}{2}{3}",
                                            Request.Url.Scheme,
                                            Request.Url.Authority,
                                            relativePath.Replace('\\', '/'),
                                            fileName
                                        ));
                vmsg.AddItem(guid);
                vmsg.IsComplete = true;
            }
            else
            {
                vmsg.AddItemRange(this.GetRuleViolations(type, hpf));
                vmsg.IsComplete = false;
            }
            return vmsg;
        }
        /// <summary>
        /// 上传到图像服务器
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public VMessage ImageToServer(string url)
        {
            VMessage vmsg = new VMessage();
            Uri uri = new Uri(url);
            string fileName = uri.Segments[uri.Segments.Length - 1];
            string typeStr = uri.Segments[uri.Segments.Length - 2];

            Utils.FileUpLoad(
                string.Format(WebConstConfig.DefaultUploadUri, typeStr.TrimEnd('/')),
                HttpContext.Current.Server.MapPath(uri.LocalPath)
                );
            vmsg.IsComplete = true;
            vmsg.AddItem(
                string.Format("{0}://{1}/upload/{2}{3}",
                    HttpContext.Current.Request.Url.Scheme,
                    WebConstConfig.ImageServerHost,
                    typeStr,
                    fileName
                )
            );
            return vmsg;
        }
        /// <summary>
        /// 上传到图像服务器
        /// </summary>
        /// <param name="stream"></param>
        /// <returns></returns>
        public VMessage ImageToServer(Byte[] stream)
        {
            VMessage vmsg = new VMessage();

            Web.Service.com.server.img.WS ins = new Web.Service.com.server.img.WS();
            string path = ins.UploadImageFile(stream);
            if (string.IsNullOrEmpty(path))
            {
                vmsg.IsComplete = false;
            }
            else
            {
                vmsg.IsComplete = true;
                vmsg.AddItem(path);
            }
            return vmsg;
        }

        #endregion

        #region 验证文件

        /// <summary>
        /// 文件是否有效
        /// </summary>
        /// <param name="type"></param>
        /// <param name="hpf"></param>
        /// <returns></returns>
        internal bool IsImageVaild(UpLoadType type, HttpPostedFileBase hpf)
        {
            return this.GetRuleViolations(type, hpf).Count() == 0;
        }
        /// <summary>
        /// 验证文件
        /// </summary>
        /// <param name="hpf"></param>
        /// <returns></returns>
        internal IEnumerable<string> GetRuleViolations(UpLoadType type, HttpPostedFileBase hpf)
        {
            if (!imgMIME.Contains(hpf.ContentType))// MIME
                yield return msgDIC[WarnEnum.ImgContentType];

            int contentLength = this.GetContentLengthByType(type);//文件大小
            if (hpf.ContentLength > contentLength)
                yield return string.Format(msgDIC[WarnEnum.ImgContentLength], contentLength / 1024);

            if (!imgExtension.Contains(hpf.FileName.Substring(hpf.FileName.LastIndexOf('.') + 1).ToLower()))//文件后缀
                yield return msgDIC[WarnEnum.ImgExtension];

            yield break;

        }
        #endregion

        #region 根据 FileUpLoadContentLengthType 类型 获取相应的大小
        /// <summary>
        /// 根据 FileUpLoadContentLengthType 类型 获取相应的大小
        /// </summary>
        /// <param name="type">文件上传大小枚举值</param>
        /// <returns>返回</returns>
        int GetContentLengthByType(UpLoadType type)
        {
            switch (type)
            {
                case UpLoadType.Resource:
                    return 200000000; //200M
                case UpLoadType.FileUrl:
                    return 200000000;
                case UpLoadType.Image:
                    return 20000000;
                case UpLoadType.ItemImage:
                    return 10000000;
                case UpLoadType.CategoryIcon:
                    return 10000000;
                default:
                    throw new Exception("可能有错误");
            }
        }
        #endregion

        #region 图像缩放
        public void CreateThumbnail(HttpPostedFileBase file, double width, double height)
        {
            CreateThumbnail(file, width, height, true);
        }
        /// <summary>
        /// 建立压缩图片
        /// </summary>
        /// <param name="file"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="isEqualScale">是否等比例缩放</param>
        public void CreateThumbnail(HttpPostedFileBase file, double width, double height, bool isEqualScale)
        {
            double wRate = 1, hRate = 1, setRate = 1;
            System.Drawing.Image image = System.Drawing.Image.FromStream(file.InputStream);
            if (isEqualScale)
            {
                if (image.Height > height)
                {
                    hRate = height / image.Height;
                }
                if (image.Width > width)
                {
                    wRate = width / image.Width;
                }
                if (wRate != 1 || hRate != 1)
                {
                    if (wRate > hRate)
                    {
                        setRate = hRate;
                    }
                    else
                    {
                        setRate = wRate;
                    }
                }
            }
            Bitmap bit = new Bitmap((int)(image.Width * setRate), (int)(image.Height * setRate));
            Rectangle r = new Rectangle(0, 0, (int)(image.Width * setRate), (int)(image.Height * setRate));
            Graphics g = Graphics.FromImage(bit);
            g.DrawImage(image, r);
            MemoryStream ms = new MemoryStream();
            bit.Save(ms, ImageFormat.Jpeg);
            byte[] bytes = ms.ToArray();
            using (FileStream stream =
                new FileStream(GetOutputFile(this.currPath, this.currFileName, (int)width, (int)height), FileMode.Create, FileAccess.Write))
            {
                stream.Write(bytes, 0, bytes.Length);
            }
            bit.Dispose();
            ms.Dispose();
            image.Dispose();
        }
        #endregion

        #region 输出地址
        /// <summary>
        /// 输出地址格式化
        /// </summary>
        /// <param name="currPath"></param>
        /// <param name="currFileName"></param>
        /// <returns></returns>
        public static string GetOutputFile(string currPath, string currFileName)
        {
            return Path.Combine(currPath, currFileName);
        }
        /// <summary>
        /// 输出地址格式化
        /// </summary>
        /// <param name="currPath"></param>
        /// <param name="currFileName"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns></returns>
        public static string GetOutputFile(string currPath, string currFileName, int width, int height)
        {
            return Path.Combine(currPath //固定为JPG
                , string.Format("{0}_{1}×{2}.jpg", currFileName, width, height));
        }
        #endregion

        #region 图片结构和尺寸规格
        /// <summary>
        /// 图片尺寸 数组
        /// </summary>
        public static ImageSize[] ImageSizeArr = { 
                                                  new ImageSize(120, 90), 
                                                  new ImageSize(350, 280), 
                                                  new ImageSize(600, 480), 
                                                };

        /// <summary>
        /// 图片尺寸结构
        /// </summary>
        public struct ImageSize
        {
            public int Width { get; private set; }
            public int Height { get; private set; }

            public ImageSize(int width, int height)
                : this()
            {
                this.Width = width;
                this.Height = height;
            }
        }
        #endregion


    }
}
